/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 prefabware.com Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel.reference;

import com.prefabware.jmodel.JArgument;
import com.prefabware.jmodel.JField;
import com.prefabware.jmodel.JMethod;
import com.prefabware.jmodel.JType;
import com.prefabware.jmodel.annotation.JAnnotation;

public class JReferenceBase<HOLDER> implements JReference<HOLDER> {

	private JType from;
	private JType to;
	private HOLDER holder;

	public JReferenceBase(JType from, JType to, HOLDER holder) {
		super();
		this.from = from;
		this.to = to;
		this.holder = holder;
	}

	@Override
	public JType getFrom() {
		return from;
	}

	@Override
	public JType getTo() {
		return to;
	}

	public HOLDER getHolder() {
		return holder;
	}

	public static JReference<?> create(JType from, JType to, Object holder) {
		if (holder instanceof JMethod) {
			return new JReferenceMethod(from, to, (JMethod) holder);
		} else if (holder instanceof JArgument) {
			return new JReferenceArgument(from, to, (JArgument) holder);
		} else if (holder instanceof JField) {
			return new JReferenceField(from, to, (JField) holder);
		} else if (holder instanceof JAnnotation) {
			return new JReferenceAnnotation(from, to, (JAnnotation) holder);
		} else if (holder instanceof JType) {
			return new JReferenceTypeArgument(from, to, (JType) holder);
		} else {
			throw new IllegalArgumentException(
					String.format(
							"cannot create a reference %n from : %s %n to : %s %n container %s",
							from, to, holder));
		}
	}

}
